From 987bcd87290282637348980aaff237ef2cdf2e49 Mon Sep 17 00:00:00 2001 From: Robert Lipe Date: Sun, 27 Dec 2020 03:13:10 -0600 Subject: [PATCH] Modernize time handling in compegps, globalsat, hiketech, jtr, magproto, util. --- compegps.cc | 67 ++++++++++++++------------------------- defs.h | 1 - globalsat_sport.cc | 1 - hiketech.cc | 14 ++------- jtr.cc | 78 +++++++++++++++++++--------------------------- magproto.cc | 18 +++++------ util.cc | 19 ----------- 7 files changed, 65 insertions(+), 133 deletions(-) diff --git a/compegps.cc b/compegps.cc index 5be0d50bf..0f5452506 100644 --- a/compegps.cc +++ b/compegps.cc @@ -122,30 +122,21 @@ void fix_datum(double* lat, double* lon) } static void -compegps_parse_date(const char* c, struct tm* tm) +compegps_parse_date(const char* c, QDate& date) { - char month[4]; - tm->tm_mday = atoi(c); - strncpy(month, c+3, 3); - month[3] = 0; - tm->tm_mon = month_lookup(month); - int year = atoi(c + 7); - if (year < 70) { - year += 100; - } - if (year > 1900) { - year -= 1900; + date = QDate::fromString(c, "dd-MMM-yy"); + // If that worked, fix 1900 bias to 2000 bias. Some have full 4 digits. + if (date.isValid()) { + date = date.addYears(100); + } else { + date = QDate::fromString(c, "dd-MMM-yyyy"); } - tm->tm_year = year; - // if (tm->tm_year < 70) tm->tm_year += 100; } static void -compegps_parse_time(const char* c, struct tm* tm) +compegps_parse_time(const char* c, QTime& time) { - tm->tm_hour = atoi(c); - tm->tm_min = atoi(c+3); - tm->tm_sec = atoi(c+6); + time = QTime::fromString(c, "hh:mm:ss"); } /* specialized readers */ @@ -156,9 +147,9 @@ parse_wpt(char* buff) int col = -1; char* cx; auto* wpt = new Waypoint; - struct tm tm; int has_time = 0; - memset(&tm, 0, sizeof(tm)); + QDate date; + QTime time; char* c = strstr(buff, "A "); if (c == buff) { @@ -196,13 +187,13 @@ parse_wpt(char* buff) case 4: if (strcmp(c, "27-MAR-62")) { has_time = 1; - compegps_parse_date(c, &tm); + compegps_parse_date(c, date); } break; case 5: if (has_time) { - compegps_parse_time(c, &tm); - wpt->SetCreationTime(mkgmtime(&tm)); + compegps_parse_time(c, time); + wpt->SetCreationTime(QDateTime(date, time, Qt::UTC)); } break; case 6: @@ -271,15 +262,15 @@ static Waypoint* parse_trkpt(char* buff) { int col = -1; - struct tm tm; auto* wpt = new Waypoint; + QDate date; + QTime time; char* c = strstr(buff, "A "); if (c == buff) { col++; } - memset(&tm, 0, sizeof(tm)); c = csv_lineparse(buff, " ", "", col++); while (c != nullptr) { c = lrtrim(c); @@ -295,11 +286,11 @@ parse_trkpt(char* buff) human_to_dec(c, nullptr, &wpt->longitude, 2); break; case 4: - compegps_parse_date(c, &tm); + compegps_parse_date(c, date); break; case 5: - compegps_parse_time(c, &tm); - wpt->SetCreationTime(mkgmtime(&tm)); + compegps_parse_time(c, time); + wpt->SetCreationTime(QDateTime(date, time, Qt::UTC)); break; case 7: wpt->altitude = atof(c); @@ -539,31 +530,19 @@ write_track_hdr_cb(const route_head* trk) static void write_trkpt_cb(const Waypoint* wpt) { - char buff[128]; - if ((curr_index != target_index) || (wpt == nullptr)) { return; } - buff[0] = '\0'; - -// TOOD: This should probably attempt a gmtime and then fall back to the 1-1-1970 -// case or bypass the time_t completely and build string representations directly. - if (wpt->creation_time.isValid()) { - const time_t tt = wpt->GetCreationTime().toTime_t(); - struct tm tm = *gmtime(&tt); - - strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); - strupper(buff); - } else { - strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); - } + QDateTime default_dt(QDate(1970,1,1), QTime(0,0,0), Qt::UTC); + auto dt = wpt->creation_time.isValid() ? wpt->GetCreationTime() : default_dt; + QString buff = dt.toString("dd-MMM-yy hh:mm:ss").toUpper(); gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", - buff, + CSTR(buff), wpt->altitude, 0.0, 0.0, diff --git a/defs.h b/defs.h index 604d02528..e35dc2625 100644 --- a/defs.h +++ b/defs.h @@ -1121,7 +1121,6 @@ time_t mkgmtime(struct tm* t); bool gpsbabel_testmode(); gpsbabel::DateTime current_time(); void dotnet_time_to_time_t(double dotnet, time_t* t, int* millisecs); -signed int month_lookup(const char* m); const char* get_cache_icon(const Waypoint* waypointp); const char* gs_get_cachetype(geocache_type t); const char* gs_get_container(geocache_container t); diff --git a/globalsat_sport.cc b/globalsat_sport.cc index af755f97b..fceea5505 100644 --- a/globalsat_sport.cc +++ b/globalsat_sport.cc @@ -636,7 +636,6 @@ GlobalsatSportFormat::track_read() } auto* wpt = new Waypoint(); // waypt_new(); - //wpt->creation_time = mkgmtime(&gpstime); wpt->SetCreationTime(gpsDateTime); wpt->longitude = ((int32_t) point.Longitude) / 1000000.0; wpt->latitude = ((int32_t) point.Latitude) / 1000000.0; diff --git a/hiketech.cc b/hiketech.cc index cd3f02e3f..2dee6dab7 100644 --- a/hiketech.cc +++ b/hiketech.cc @@ -255,18 +255,8 @@ void ht_trk_pnt_e(xg_string, const QXmlStreamAttributes*) static void ht_trk_utc(xg_string args, const QXmlStreamAttributes*) { - struct tm tm; - - sscanf(CSTRc(args), "%d-%d-%d %d:%d:%d", - &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - - time_t utc = mkgmtime(&tm); - + QDateTime utc = QDateTime::fromString(args, "yyyy-MM-dd hh:mm:ss"); + utc.setTimeSpec(Qt::UTC); wpt_tmp->SetCreationTime(utc); } diff --git a/jtr.cc b/jtr.cc index e96f9f32b..7ae83190a 100644 --- a/jtr.cc +++ b/jtr.cc @@ -37,44 +37,37 @@ QVector jtr_args = { static gbfile* fin, *fout; static QHash trkpts; -static time_t -jtr_parse_time(const char* str, struct tm* tm, int* milli) -{ - char* dot; - - long int hms = strtol(str, &dot, 10); - if (hms > 0) { - tm->tm_sec = hms % 100; - hms = hms / 100; - tm->tm_min = hms % 100; - hms = hms / 100; - tm->tm_hour = hms % 100; - - if ((*dot == '.') && (milli != nullptr)) { - *milli = atoi(dot + 1) * 10; - } - - return mkgmtime(tm); - } else { - return 0; - } -} - -static time_t -jtr_parse_date(const char* str, struct tm* tm) +void +jtr_parse_date(const char* str, QDate& date) { int dmy = atoi(str); - if (dmy > 0) { - tm->tm_year = dmy % 100 + 100; + int year= dmy % 100 + 2000; dmy = dmy / 100; - tm->tm_mon = dmy % 100 - 1; + int month = dmy % 100; dmy = dmy / 100; - tm->tm_mday = dmy; - return mkgmtime(tm); - } else { - return 0; + int day = dmy; + date = QDate(year, month, day); + } +} + +void +jtr_parse_time(const char* str, QTime& time) +{ + char* dot; + long int hms = strtol(str, &dot, 10); + int sec = hms % 100; + hms = hms / 100; + int min = hms % 100; + hms = hms / 100; + int hour = hms % 100; + + if (*dot == '.') { + int milli = atoi(dot + 1) * 10; + sec += milli / 1000; } + + time = QTime(hour, min, sec); } /******************************************************************************* @@ -102,12 +95,11 @@ jtr_read() route_head* trk = nullptr; while ((str = gbfgetstr(fin))) { - struct tm tm; + QDate date; + QTime time; char valid = 'V'; double lon; float course, mcourse, mvar, mdev; - time_t time = 0; - int mills = 0; char buf[32]; char mdevdir; @@ -122,7 +114,6 @@ jtr_read() fatal(MYNAME ": Unknown or unsupported file (missing \"GEOTAG2\")!\n"); } - memset(&tm, 0, sizeof(tm)); double lat = lon = 999; float speed = course = mcourse = mvar = mdev = -1; char mvardir = mdevdir = 0; @@ -140,7 +131,7 @@ jtr_read() case 0: break; /* GEOTAG2 */ case 1: - jtr_parse_time(str, &tm, &mills); + jtr_parse_time(str, time); break; case 2: valid = *str; @@ -168,7 +159,7 @@ jtr_read() course = atof(str); break; case 9: - jtr_parse_date(str, &tm); + jtr_parse_date(str, date); break; case 13: mcourse = atof(str); @@ -194,15 +185,10 @@ jtr_read() continue; } - if (tm.tm_year > 0) { - time = mkgmtime(&tm); - } else { - time = 0; - } + QDateTime dt = QDateTime(date, time, Qt::UTC); /* check for duplicates as suggested in format description */ - - snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)time); + snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)dt.toTime_t()); if (trkpts.contains(QString::fromUtf8(buf))) { continue; } @@ -211,7 +197,7 @@ jtr_read() wpt->latitude = lat; wpt->longitude = lon; - wpt->SetCreationTime(time, mills); + wpt->SetCreationTime(dt); if (speed >= 0) { WAYPT_SET(wpt, speed, speed); } diff --git a/magproto.cc b/magproto.cc index 6a968b5c1..38e326594 100644 --- a/magproto.cc +++ b/magproto.cc @@ -26,7 +26,6 @@ #include // for sscanf, size_t #include // for atoi, atof, strtoul #include // for strchr, strncmp, strlen, memmove, strrchr, memset -#include // for gmtime #include // for QByteArray #include // for QDateTime @@ -995,20 +994,19 @@ mag_trkparse(char* trkmsg) /* Field 8 is constant */ /* Field nine is optional track name */ int dmy = atoi(ifield[10]); - - tm.tm_sec = hms % 100; + int sec = hms % 100; hms = hms / 100; - tm.tm_min = hms % 100; + int min = hms % 100; hms = hms / 100; - tm.tm_hour = hms % 100; + int hour = hms % 100; - tm.tm_year = 100 + dmy % 100; + int year = 100 + dmy % 100 + 1900; dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; + int mon = dmy % 100; dmy = dmy / 100; - tm.tm_mday = dmy % 100; - - waypt->SetCreationTime(mkgmtime(&tm), 10.0 * fracsecs); + int day = dmy % 100; + QDateTime dt(QDate(year, mon, day), QTime(hour, min, sec, fracsecs * 10), Qt::UTC); + waypt->SetCreationTime(dt); if (latdir == 'S') { latdeg = -latdeg; diff --git a/util.cc b/util.cc index 448f64e3e..c3531a73f 100644 --- a/util.cc +++ b/util.cc @@ -756,25 +756,6 @@ current_time() return QDateTime::currentDateTimeUtc(); } -/* - * Return the (zero based) month number of the year or -1 for failure. - */ -signed int -month_lookup(const char* m) -{ - static const char* months[] = { - "JAN", "FEB", "MAR", "APR", "MAY", "JUN", - "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", nullptr - }; - - for (const char** mp = months; *mp; mp++) { - if (0 == case_ignore_strcmp(*mp, m)) { - return mp - months; - } - } - return -1; -} - /* * Microsoft dot net's time format is the number of 100 nanosecond intervals * since midnight Jan 1, 0001. We have time_t deeply ingrained into our -- 2.30.2